#include "Enemy.h"
#include "MainCharacter.h"
#include "Bullet.h"
#include "Weapon.h"
#include "ShootEmUp.h"
#include "GameManager.h"
#include "LevelManager.h"

using namespace Ogre;
using namespace std;

int Enemy::ID=0;
const char* Enemy::DEFAULT_NAME="enemy_";
const char* Enemy::DEFAULT_NODE_NAME="EnemyNode";
static int idPartiicle = 0;

Enemy::Enemy()
: Character(Enemy::DEFAULT_NAME + StringConverter::toString(Enemy::ID)),
mTimeUntilNextBullet(-1.0f),
weapon(0),
pSys2(0)
{
	mSceneMgr = ShootEmUp::getSingleton().getSceneManager();
	weapon = GameManager::getSingleton().createWeapon(Weapon::BUG, Weapon::LEVEL1);
	Enemy::ID++;
	moveSpeed=ShootEmUp::getSingleton().getScrollingSpeed();
	// Init sounds
	SoundManager::getSingletonPtr()->loadAudio("Desintegr.wav", &desintegrSoundId, false);
}

Enemy::~Enemy()
{	
}

void Enemy::collision(Item* _item)
{
	_item->collisionWithEnemy( this );
}

void Enemy::collisionWithBullet(Bullet* bullet)
{
	Weapon* weapon = bullet->getWeapon();

	if ( weapon->getWeaponType() != Weapon::BUG )
	{
		SoundManager::getSingletonPtr()->playAudio( desintegrSoundId, true );
		weapon->destroyBullet( bullet );
		//effet explosion

		//pSys2 = 0;//new Ogre::ParticleSystem();
		pSys2 =  mSceneMgr->createParticleSystem("fountain" + StringConverter::toString(idPartiicle), "Explosion/Enemy");
		idPartiicle++;
		mSceneNode->attachObject( pSys2 );
		if(nbTouch >= 0)
			nbTouch--;
		if(nbTouch <= 0)
		{
			GameManager::getSingleton().destroyEnemy( this );
			MainCharacter::getSingleton().addScore( health );
			ShootEmUp::getSingleton().showFish( true );
			initNbTouch();
			LevelManager::getSingleton().callForNewWeapon( mSceneNode->getPosition() );
		}

	}
}

void Enemy::collisionWithEnemy(Enemy* _enemy)
{
	renewDestination();
	_enemy->renewDestination();
}


void Enemy::collisionWithFish(Fish * _fish){
}

void Enemy::collisionWithMainCharacter(MainCharacter* _mainCharacter)
{
	if(!_mainCharacter->getShield())
	{

		//if(_mainCharacter->getLives() <= 0){
		//	ShootEmUp::getSingleton().menuFin();
		//}

		_mainCharacter->liveLost();
		ShootEmUp::getSingleton().showFish( true );
		if(!(_mainCharacter->getLives() <= 0))
			_mainCharacter->getSceneNode()->setPosition(0,0,0);
		_mainCharacter->setShield(true);
	}
}

void Enemy::collisionWithBonus(Bonus* _bonus)
{}

void Enemy::collisionWithWeapon(Weapon* weapon)
{}

bool Enemy::move()
{
	if (mDirection == Vector3::ZERO) 
	{
		if (nextLocation()) 
		{
		}
	}
	else
	{
		Real move = moveSpeed;// * evt.timeSinceLastFrame;
		mDistance -= move;

		if (mDistance <= 0.0f)
		{
			mSceneNode->setPosition(mDestination);
			mDirection = Vector3::ZERO;

			// Set animation based on if the robot has another point to walk to. 
			if (! nextLocation())
			{
				// Set Idle animation
				//mAnimationState = mEntity->getAnimationState("Idle");
				//mAnimationState->setLoop(true);
				//mAnimationState->setEnabled(true);
				GameManager::getSingleton().destroyEnemy( this );
			} 
			else
			{
				// Rotation Code will go here later
			}
		}
		else
		{
			mSceneNode->translate(mDirection * move);
		} // else
	} // if

	//mAnimationState->addTime(evt.timeSinceLastFrame);
	return true;
}

bool Enemy::frameStarted(const FrameEvent& evt)
{
	if (mTimeUntilNextBullet >= 0)
		mTimeUntilNextBullet -= evt.timeSinceLastFrame;
	else
	{
		weapon->createBullet( mSceneNode->getPosition() );
		mTimeUntilNextBullet = Ogre::Math::RangeRandom(3.f, 6.f);
	}
	move();
	return true;
}

void Enemy::renewDestination()
{
	mSceneNode->translate(mDirection * (-moveSpeed * 8));
	mDestination = mSceneNode->getPosition() + (mSceneNode->getPosition() - mDestination);
	mDirection = mDestination - mSceneNode->getPosition();
	mDistance = mDirection.normalise();
}

bool Enemy::nextLocation()
{
	if ( mSceneNode->getPosition().z <= (ShootEmUp::WORLD_MIN.z - 100) )
		return false;

	mDestination = Vector3( 
		Math::RangeRandom(ShootEmUp::WORLD_MIN.x, ShootEmUp::WORLD_MAX.x), 
		Math::RangeRandom(ShootEmUp::WORLD_MIN.y, ShootEmUp::WORLD_MAX.y), 
		Math::RangeRandom(ShootEmUp::WORLD_MIN.z - 150, mSceneNode->getPosition().z) 
		);

	mDirection = mDestination - mSceneNode->getPosition();
	mDistance = mDirection.normalise();
	/*
	Vector3 src = mSceneNode->getOrientation() * Vector3::UNIT_X;
	if ((1.0f + src.dotProduct(mDirection)) < 0.0001f) 
	{
		mSceneNode->yaw(Degree(180));
	}
	else
	{
		Quaternion quat = src.getRotationTo(mDirection);
		mSceneNode->rotate(quat);
	} // else
	*/
	return true;
}

void Enemy::reset()
{
	mDirection = Vector3::ZERO;
	mDistance = 0.f;
	mDirection = Vector3::ZERO;
	mDestination = Vector3::ZERO;

	Vector3 initialPosition( 
		Math::RangeRandom(ShootEmUp::WORLD_MIN.x, ShootEmUp::WORLD_MAX.x), 
		Math::RangeRandom(ShootEmUp::WORLD_MIN.y, ShootEmUp::WORLD_MAX.y), 
		ShootEmUp::WORLD_MAX.z
		);
	mSceneNode->setPosition( initialPosition );
	if ( mEntity->isAttached() )
		mEntity->getParentSceneNode()->detachObject( mEntity );
	mSceneNode->attachObject( mEntity );


	//detach the particle

	if ( pSys2 )
	{
		mSceneNode->detachObject(pSys2);
		mSceneMgr->destroyParticleSystem( pSys2 );
		pSys2 = 0;
	}

}